package myJs

import myJs.Utils._
import org.scalajs.dom.{Element, _}
import scalatags.Text.{TypedTag, all}
import scalatags.Text.all.{value, _}

import scala.collection.mutable
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.Tool.{layerOptions, myElement}
import myJs.myPkg._

import scala.scalajs.js.JSON
import myJs.myPkg.jquery._

import scala.collection.immutable.SeqMap
import scala.scalajs.js.Dynamic.{global => g}
import myJs.Implicits._
import scala.scalajs.js.JSConverters._

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("MissionManage")
object MissionManage {
  val configFormId = "configForm"
  val configModalId = "modal"
  val updateFormId = "updateForm"
  val updateModalId = "updateModal"
  val typeTagEmpty = List[TypedTag[String]]()


  @JSExport("init")
  def init = {
    initTable
    refreshMission()
    configFormBootStrapValidator
    updateFormBootStrapValidator

  }

  val operateColumn = js.Array(
    ColumnOptions.field("operate").title("数据操作").formatter(operateFmt).filterControl("clear")
  )

  val missionOperateColumn = js.Array(
    ColumnOptions.field("missionOperate").title("任务操作").formatter(missionOperateFmt).filterControl("clear")
  )

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) => columnName match {
    case _ => v
  }

  def initTable = {
    val map = SeqMap("missionName" -> "任务名", "state" -> "任务状态", "startTime" -> "开始时间", "endTime" -> "结束时间")
    val columnNames = map.keyList
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName)
      val style = expStyle(columnName)
      val basicOptions = ColumnOptions.field(columnName).title(title).sortable(true).formatter(fmt).cellStyle(style)
      columnName match {
        case x if List("size", "uploadTime", "fileName", "comment", "tags").contains(x) => basicOptions.
          sortable(false).operateable(true)
        case _ => basicOptions
      }
    }.concat(operateColumn).concat(missionOperateColumn)
    val options = TableOptions.columns(columns.toJSArray).searchOnButton(false).filterControl(false)
    $(s"#missionTable").bootstrapTable(options)
  }

  def operateFmt: js.Function = {
    (v: js.Any, row: js.Dictionary[js.Any]) =>
      val downloadUrl = g.jsRoutes.controllers.MissionController.downloadResult().url.toString
      val downloadStr = a(title := "下载结果", href := s"${downloadUrl}?missionId=${row("id")}", cursor.pointer,
        span(em(cls := "fa fa-download"))
      )
      val downloadDataUrl = g.jsRoutes.controllers.MissionController.downloadData().url.toString
      val downloadDataStr = a(title := "下载原始数据", href := s"${downloadDataUrl}?missionId=${row("id")}", cursor.pointer,
        span(em(cls := "fa fa-cloud-download"))
      )
      val viewUrl = g.jsRoutes.controllers.MissionController.reportView().url.toString
      val reportViewStr = a(title := "报告预览", href := s"${viewUrl}?missionId=${row("id")}", cursor.pointer,
        target := "_blank", span(em(cls := "fa fa-eye"))
      )

      val viewEnUrl = g.jsRoutes.controllers.MissionController.reportEnView().url.toString
      val reportViewEnStr = a(title := "英文报告预览", href := s"${viewEnUrl}?missionId=${row("id")}", cursor.pointer,
        target := "_blank", span(em(cls := "fa fa-eye-slash"))
      )

      val pdfViewUrl = g.jsRoutes.controllers.MissionController.pdfView().url.toString
      val pdfViewStr = a(title := "PDF预览", href := s"${pdfViewUrl}?missionId=${row("id")}", cursor.pointer,
        target := "_blank", span(em(cls := "fa fa-file-pdf-o"))
      )

      val state1 = if (List("success", "warning").contains(row("state"))) {
        List(reportViewStr,
          //          reportViewEnStr,
          downloadStr)
      } else List[TypedTag[String]]()
      val state2 = if (List("success", "error", "warning").contains(row("state"))) {
        List(downloadDataStr)
      } else List[TypedTag[String]]()
      val rs = state1 ::: state2
      rs.mkString("&nbsp;")

  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => columnName match {
    case "state" =>
      val state1 = if (List("success").contains(row("state"))) {
        span(cls := "label label-success", s"成功！")
      } else if (List("running").contains(row("state"))) {
        span("正在运行 ",
          img(cls := "runningImage", src := "/assets/images/running2.gif", width := 30, height := 20))
      } else if (List("wait", "preparing").contains(row("state"))) {
        span(
          span(cls := "label label-default", "排队中"),
          all.raw("&nbsp;"),
          img(cls := "runningImage", src := "/assets/images/running2.gif", width := 30, height := 20))
      } else if(List("warning").contains(row("state"))){
        span(cls := "label label-warning", "成功！")
      } else{
        span(cls := "label label-danger", "错误！")
      }
      state1.toString()
    case _ => v
  }

  @JSExport("saveConfig")
  def saveConfig = {
    val formId = configFormId
    val modalId = configModalId
    val bv = jQuery(s"#${formId}").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().asInstanceOf[Boolean]
    if (valid) {
      val data = $(s"#${formId}").serialize()
      val index = layer.alert(myElement, layerOptions)
      val url = g.jsRoutes.controllers.ConfigController.add().url.toString
      val ajaxSettings = JQueryAjaxSettings.url(url).`type`("post").data(data).success { (data, status, e) =>
        layer.close(index)
        jQuery(s"#${modalId}").modal("hide")
        bv.resetForm(true)
        Swal.swal(SwalOptions.title("成功").text("保存参数方案成功!").`type`("success"))

      }
      $.ajax(ajaxSettings)
    }
  }

  @JSExport("updateName")
  def updateName = {
    val formId = updateFormId
    val modalId = updateModalId
    val bv = jQuery(s"#${formId}").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().asInstanceOf[Boolean]
    if (valid) {
      val data = $(s"#${formId}").serialize()
      val index = layer.alert(myElement, layerOptions)
      val url = g.jsRoutes.controllers.MissionController.updateName().url.toString
      val ajaxSettings = JQueryAjaxSettings.url(url).`type`("post").data(data).success { (data, status, e) =>
        refreshMission { () =>
          layer.close(index)
          jQuery(s"#${modalId}").modal("hide")
          bv.resetForm(true)
          Swal.swal(SwalOptions.title("成功").text("修改任务名成功!").`type`("success"))
        }


      }
      $.ajax(ajaxSettings)
    }
  }

  @JSExport("refreshMission")
  def refreshMission(f: () => Any = () => ()) = {
    val url = g.jsRoutes.controllers.MissionController.getAllMission().url.toString
    val ajaxSettings = JQueryAjaxSettings.url(s"${url}?").contentType("application/json").
      `type`("get").success { (data, status, e) =>
      $("#missionTable").bootstrapTable("load", data)
      f()
    }
    $.ajax(ajaxSettings)

  }


  @JSExport("show")
  def show(missionName: String) = {
    $("#configForm input[name='missionName']").`val`(missionName)
    jQuery("#modal").modal("show")
  }

  @JSExport("updateNameShow")
  def updateNameShow(dict: js.Dictionary[String]) = {
    $("#updateForm input[name='orignalMissionName']").`val`(dict("missionName"))
    $("#updateForm input[name='missionId']").`val`(dict("id"))
    jQuery("#updateModal").modal("show")
  }

  @JSExport("missionOperateFmt")
  def missionOperateFmt: js.Function = {
    (v: js.Any, row: js.Dictionary[js.Any]) =>
      val updateNameStr = a(title := "修改任务名", onclick := s"MissionManage.updateNameShow(${JSON.stringify(row)})", cursor.pointer,
        target := "_blank", span(em(cls := "fa fa-edit"))
      )
      val deleteStr = a(title := "删除", onclick := s"deleteMission('${row("id")}')", cursor.pointer,
        span(em(cls := "fa fa-close"))
      )
      val viewStr = a(title := "日志", onclick := s"viewLog('${row("id")}')", cursor.pointer,
        span(em(cls := "fa fa-file-text"))
      )
      val produceConfigStr = a(title := "保存参数方案", onclick := s"MissionManage.show('" + row("missionName") + "')", cursor.pointer,
        target := "_blank", span(em(cls := "fa fa-wrench"))
      )
      val reRunUrl = g.jsRoutes.controllers.MissionController.reRunMissionBefore().url.toString
      val reRunStr = a(title := "重新运行", href := s"${reRunUrl}?missionId=${row("id")}", cursor.pointer,
        span(em(cls := "fa fa-refresh"))
      )

      val state1 = if (List("success", "warning").contains(row("state"))) {
        List(updateNameStr, produceConfigStr)
      } else typeTagEmpty
      val state2 = if (!List("running", "wait", "preparing").contains(row("state"))) {
        List(viewStr, reRunStr)
      } else typeTagEmpty
      val rs = state1 ::: state2 ::: List(deleteStr)

      rs.mkString("&nbsp;")

  }


  def configFormBootStrapValidator = {
    val url = g.jsRoutes.controllers.ConfigController.nameCheck().url.toString
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "configName" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "配置名不能为空！"
            ),
            "remote" -> js.Dictionary(
              "message" -> "配置名已存在！",
              "url" -> url,
              "delay" -> 1000,
              "type" -> "POST",
            ),
          )
        ),
      )
    )
    g.$("#configForm").bootstrapValidator(dict)

  }

  def updateFormBootStrapValidator = {
    val url = g.jsRoutes.controllers.MissionController.missionNameCheck().url.toString
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "missionName" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "任务名不能为空!"
            ),
            "remote" -> js.Dictionary(
              "message" -> "任务名已存在!",
              "extension" -> "csv",
              "url" -> url,
              "type" -> "POST",
              "delay" -> 1000
            ),
          )
        ),
      )
    )
    g.$("#updateForm").bootstrapValidator(dict)

  }


}
